home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 31
/
Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso
/
Aminet
/
util
/
gnu
/
xpdf-0.8-src.lha
/
xpdf-0.8-src
/
ltk
/
LTKApp.cc
< prev
next >
Wrap
C/C++ Source or Header
|
1998-11-28
|
13KB
|
477 lines
//========================================================================
//
// LTKApp.cc
//
// Copyright 1996 Derek B. Noonburg
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
#include <stdlib.h>
#include <stddef.h>
#include <unistd.h>
#ifdef HAVE_STRINGS_H
// needed by AIX for bzero() declaration for FD_ZERO
#include <strings.h>
#endif
#ifdef HAVE_BSTRING_H
// needed by IRIX for bzero() declaration for FD_ZERO
#include <bstring.h>
#endif
#ifdef HAVE_SYS_SELECT_H
// needed by some systems for fd_set
#include <sys/select.h>
#endif
#ifdef HAVE_SYS_BSDTYPES_H
// needed by some systems for fd_set
#include <sys/bsdtypes.h>
#endif
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include "gtypes.h"
#include "LTKApp.h"
#include "LTKResources.h"
#include "LTKWindow.h"
#include "LTKMenu.h"
#include "LTKMisc.h"
#include "LTKWidget.h"
#ifdef XlibSpecificationRelease
#if XlibSpecificationRelease < 5
typedef char *XPointer;
#endif
#else
typedef char *XPointer;
#endif
#ifdef VMS
extern "C" int XMultiplexInput(int num_displays,
Display *displays[],
unsigned long ef_mask,
unsigned long timeout,
unsigned long options,
long *retval_pointer);
#if defined(__DECCXX) && (_VMS_VER < 70000000)
extern "C" int gettimeofday (struct timeval *__tp, void *__tzp);
#endif
#endif
//------------------------------------------------------------------------
#define ltkSingleClickTime 200 // max time from press to release for
// a single click (in ms)
#define ltkDoubleClickTime 200 // max time from press to press for a
// double click (in ms)
//------------------------------------------------------------------------
// LTKApp
//------------------------------------------------------------------------
LTKApp::LTKApp(char *appName1, XrmOptionDescRec *opts,
int *argc, char *argv[]) {
int numOpts;
XrmDatabase cmdLineDB;
GString *displayName;
int h;
appName = new GString(appName1);
windows = NULL;
for (h = 0; h < ltkWinTabSize; ++h)
winTab[h] = NULL;
grabWin = NULL;
activeMenu = NULL;
repeatWidget = NULL;
repeatDelay = 0;
repeatPeriod = 0;
firstRepeat = gTrue;
cmdLineDB = NULL;
resourceDB = NULL;
XrmInitialize();
for (numOpts = 0; opts[numOpts].option; ++numOpts) ;
ltkGetCmdLineResources(&cmdLineDB, opts, numOpts, appName, argc, argv);
displayName = ltkGetStringResource(cmdLineDB, appName, "display", "");
if (!(display = XOpenDisplay(displayName->getCString()))) {
ltkError("Cannot connect to X server %s\n",
XDisplayName(displayName->getCString()));
exit(1);
}
delete displayName;
screenNum = DefaultScreen(display);
ltkGetOtherResources(display, cmdLineDB, &resourceDB);
wmDeleteWinAtom = XInternAtom(display, "WM_DELETE_WINDOW", False);
pressedBtn = 0;
killCbk = NULL;
}
LTKApp::~LTKApp() {
LTKWindow *w1;
while (windows) {
w1 = windows;
windows = windows->getNext();
delete w1;
}
XCloseDisplay(display);
delete appName;
}
GString *LTKApp::getStringResource(char *inst, char *def) {
return ltkGetStringResource(resourceDB, appName, inst, def);
}
int LTKApp::getIntResource(char *inst, int def) {
return ltkGetIntResource(resourceDB, appName, inst, def);
}
GBool LTKApp::getBoolResource(char *inst, GBool def) {
return ltkGetBoolResource(resourceDB, appName, inst, def);
}
unsigned long LTKApp::getColorResource(char *inst,
char *def1, unsigned long def2,
XColor *xcol) {
return ltkGetColorResource(resourceDB, appName, inst,
display, screenNum, def1, def2, xcol);
}
XFontStruct *LTKApp::getFontResource(char *inst, char *def) {
return ltkGetFontResouce(resourceDB, appName, inst, display, screenNum, def);
}
void LTKApp::getGeometryResource(char *inst, int *x, int *y,
Guint *width, Guint *height) {
ltkGetGeometryResource(resourceDB, appName, inst, display, screenNum,
x, y, width, height);
}
LTKWindow *LTKApp::addWindow(LTKWindow *w) {
w->setNext(windows);
windows = w;
return w;
}
LTKWindow *LTKApp::delWindow(LTKWindow *w) {
LTKWindow *w1, *w2;
int h;
LTKWinHash *p1, *p2, *p3;
for (w1 = NULL, w2 = windows; w2 && w2 != w; w1 = w2, w2 = w2->getNext()) ;
if (w2 == w) {
// remove window from window list
if (w1)
w1->setNext(w2->getNext());
else
windows = w2->getNext();
w2->setNext(NULL);
// remove window and widgets from hash table
for (h = 0; h < ltkWinTabSize; ++h) {
p1 = NULL;
p2 = winTab[h];
while (p2) {
if (p2->win == w) {
p3 = p2;
if (p1)
p2 = p1->next = p2->next;
else
p2 = winTab[h] = p2->next;
delete p3;
} else {
p1 = p2;
p2 = p2->next;
}
}
}
return w2;
}
return NULL;
}
void LTKApp::registerXWindow(Window xwin, LTKWindow *win, LTKWidget *widget) {
int h;
LTKWinHash *p;
h = (int)xwin % ltkWinTabSize;
p = new LTKWinHash;
p->xwin = xwin;
p->win = win;
p->widget = widget;
p->next = winTab[h];
winTab[h] = p;
}
LTKWindow *LTKApp::findWindow(Window xwin, LTKWidget **widget) {
int h;
LTKWinHash *p;
h = (int)xwin % ltkWinTabSize;
for (p = winTab[h]; p; p = p->next) {
if (p->xwin == xwin) {
*widget = p->widget;
return p->win;
}
}
*widget = NULL;
return NULL;
}
void LTKApp::setRepeatEvent(LTKWidget *repeatWidget1, int repeatDelay1,
int repeatPeriod1) {
repeatWidget = repeatWidget1;
repeatDelay = repeatDelay1;
repeatPeriod = repeatPeriod1;
firstRepeat = gTrue;
gettimeofday(&lastRepeat, NULL);
}
void LTKApp::doEvent(GBool wait) {
#ifdef VMS
long delay, retval;
#else
fd_set readFDs, writeFDs, exceptFDs;
#endif
struct timeval curTime, timeout;
int timeout1;
XEvent event;
XEvent event2;
Window pointerRoot, pointerChild;
LTKWindow *win;
LTKWidget *widget;
LTKMenu *menu;
KeySym key;
GString *str;
char buf[20];
Atom typeRet;
int formatRet;
unsigned long length, left;
unsigned char *bufPtr;
GBool click, dblClick;
int x, y, rx, ry;
unsigned int mask;
int n, i;
while (XPending(display) == 0) {
if (!wait)
return;
#ifndef VMS
FD_ZERO(&readFDs);
FD_ZERO(&writeFDs);
FD_ZERO(&exceptFDs);
n = ConnectionNumber(display);
FD_SET(n, &readFDs);
#endif
if (!repeatWidget) {
#ifdef VMS
n = XMultiplexInput(1, &display, 0, 0, 0, &retval);
#else // VMS
#ifdef SELECT_TAKES_INT
n = select(n+1, (int *)&readFDs, (int *)&writeFDs, (int *)&exceptFDs,
NULL);
#else
n = select(n+1, &readFDs, &writeFDs, &exceptFDs, NULL);
#endif
#endif // VMS
} else {
gettimeofday(&curTime, NULL);
timeout.tv_sec = curTime.tv_sec - lastRepeat.tv_sec;
if (curTime.tv_usec < lastRepeat.tv_usec) {
--timeout.tv_sec;
timeout.tv_usec = (1000000 + curTime.tv_usec) - lastRepeat.tv_usec;
} else {
timeout.tv_usec = curTime.tv_usec - lastRepeat.tv_usec;
}
timeout1 = firstRepeat ? repeatDelay : repeatPeriod;
if (timeout.tv_sec > 0 || timeout.tv_usec > timeout1)
timeout.tv_usec = 0;
else
timeout.tv_usec = timeout1 - timeout.tv_usec;
timeout.tv_sec = 0;
#ifdef VMS
if ((delay = timeout.tv_usec / 1000) == 0)
delay = 1;
n = XMultiplexInput(1, &display, 0, delay, 0, &retval);
#else // VMS
#ifdef SELECT_TAKES_INT
n = select(n+1, (int *)&readFDs, (int *)&writeFDs, (int *)&exceptFDs,
&timeout);
#else
n = select(n+1, &readFDs, &writeFDs, &exceptFDs, &timeout);
#endif
#endif // VMS
}
if (n == 0 && repeatWidget) {
repeatWidget->repeatEvent();
firstRepeat = gFalse;
gettimeofday(&lastRepeat, NULL);
return;
}
}
XNextEvent(display, &event);
win = findWindow(event.xany.window, &widget);
if (activeMenu && event.xany.window == activeMenu->getXWindow())
menu = activeMenu;
else
menu = NULL;
switch (event.type) {
case Expose:
// redraw the window or widget, ignoring all but the last
// Expose event for that window
if (event.xexpose.count == 0) {
if (widget)
widget->redraw();
else if (win)
win->redrawBackgro